﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.Collections.Generic;
using Sebarf.Diagnostics.Interfaces;
using Sebarf.Security.Interfaces;
using Sebarf.Services.Interfaces;
using Sebastof.Services.Impl.DataHandlingStrategies;
using Sebastof.Services.Interfaces;

#endregion

namespace Sebastof.Server.Services.Impl {
	/// <summary>
	/// uses the LazyLoadingDataHandlingStrategy to restore the data
	/// Impl of <see cref="IDataHandlingStrategyService"/>
	/// </summary>
	public class LazyLoadingSerializationDataHandlingStrategyService : Service, ISerializationDataHandlingStrategyService {
		#region Public Properties

		[ServiceRequest(IsOptional = true)]
		public IAuthorizationService AuthorizationService { get; set; }

		public bool ExcludeValueTypesFromLazyLoading { get; set; }

		public bool EnableSecurity { get; set; }

		#endregion

		#region Public Methods

		public LazyLoadingSerializationDataHandlingStrategyService() {
			ExcludeValueTypesFromLazyLoading = true;
		}

		#endregion

		#region ISerializationDataHandlingStrategyService Members

		public Dictionary<string, object> GetDataToTransferFromObject(object obj) {
			var iObject = obj as ISebastofApplicationObject;
			Check.ArgumentNotNull(iObject, "iObject");
			var toReturn = new Dictionary<string, object>();
			if (ExcludeValueTypesFromLazyLoading) {
				// prepare data to transmit
				foreach (var val in iObject.GetValues()) {
					// transmit only value types || strings
					if (val.Value is ValueType || val.Value is String) {
						// security checks
						if (!EnableSecurity || AuthorizationService.CheckAccess("ReadField", GetSecurityArguments(val.Key))) {
							toReturn.Add(val.Key, val.Value);
						}
						else {
							// submit access denied value
							toReturn.Add(val.Key, new AccessDeniedValue());
							Logger.WriteDebug("Reading of " + val.Key + " has been denied");
						}
					}
				}
			}
			return toReturn;
		}

		public void RestoreObjectFromTransferedData(object obj, Dictionary<string, object> data) {
			throw new NotImplementedException();
		}

		#endregion

		public override void DoSetup() {
			base.DoSetup();
			if (EnableSecurity) {
				Check.ArgumentNotNull(AuthorizationService, "AuthorizationService");
			}
		}

		#region Private Methods

		private Dictionary<string, object> GetSecurityArguments(string fieldName) {
			var toReturn = new Dictionary<string, object>();
			toReturn.Add("FieldName", fieldName);
			return toReturn;
		}

		#endregion
	}
}